package com.hanxiaozhang.system.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

import com.hanxiaozhang.annotation.EnableGlobalException;
import com.hanxiaozhang.exception.DataNotFoundException;
import com.hanxiaozhang.exception.ParameterNotValidException;
import com.hanxiaozhang.result.Result;
import com.hanxiaozhang.system.dto.DeptDTO;
import com.hanxiaozhang.system.dto.TreeDTO;
import com.hanxiaozhang.system.entity.DeptEntity;
import com.hanxiaozhang.util.PageUtil;
import com.hanxiaozhang.validation.util.ValidationUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import com.hanxiaozhang.system.entity.DeptEntity;
import com.hanxiaozhang.system.service.DeptService;


/**
 * 部门表
 *
 * @author hanxiaozhang
 * @email hanxiaozhang2018@sina.com
 * @date 2021-03-21
 */
@Slf4j
@Controller
@RequestMapping("/dept")
@EnableGlobalException
public class DeptController {

    @Autowired
    private DeptService deptService;

    /**
     * 查询列表
     *
     * @param params
     * @return
     */
    @ResponseBody
    @GetMapping("/list")
    @PreAuthorize("hasAuthority('system:dept:list')")
    public Result list(@RequestParam Map<String, Object> params) {
        List<DeptDTO> deptList = deptService.list(params);
        handleChildrenNode(deptList);
        return Result.success(deptList);
    }

    /**
     * 处理孩子节点
     *
     * @param deptList
     */
    private void handleChildrenNode(List<DeptDTO> deptList) {
        if (deptList.isEmpty()) {
            return;
        }
        List<DeptDTO> allDeptList = deptService.list(new HashMap<>(4));
        listDeptRecursion(deptList, "无", allDeptList);
    }

    /**
     * 递归查询
     *
     * @param deptList
     * @param parentName
     * @param allDeptList
     */
    private void listDeptRecursion(List<DeptDTO> deptList, String parentName, List<DeptDTO> allDeptList) {
        if (!deptList.isEmpty()) {
            deptList.forEach(x -> {
                Long deptId = x.getDeptId();
                List<DeptDTO> childrenList = allDeptList.stream().filter(y -> deptId.equals(y.getParentId())).collect(Collectors.toList());
                x.setParentName(parentName);
                x.setChildren(childrenList);
                listDeptRecursion(childrenList, x.getDeptName(), allDeptList);
            });
        }
        return;
    }


    /**
     * 保存
     *
     * @param dept
     * @return
     */
    @ResponseBody
    @PostMapping("/save")
    @PreAuthorize("hasAuthority('system:dept:save')")
    public Result<Void> save(DeptDTO dept) {
        valid(dept);
        deptService.save(dept);
        return Result.success();
    }


    /**
     * 修改
     *
     * @param dept
     * @return
     */
    @ResponseBody
    @PostMapping("/update")
    @PreAuthorize("hasAuthority('system:dept:update')")
    public Result<Void> update(DeptDTO dept) {
        valid(dept);
        deptService.update(dept);
        return Result.success();
    }


    /**
     * 参数校验
     *
     * @param dept
     */
    private void valid(DeptDTO dept) {
        ValidationUtil.checkParameter(ValidationUtil.checkObjectIsNotNull(dept.getDeptName()),"部门名称不能为空");
        ValidationUtil.checkParameter(ValidationUtil.checkObjectIsNotNull(dept.getDeptOrder()),"部门排序不能为空");
    }


    /**
     * 删除
     *
     * @param deptId
     * @return
     */
    @PostMapping("/remove")
    @ResponseBody
    @PreAuthorize("hasAuthority('system:dept:remove')")
    public Result remove(Long deptId,Long parentId) {

        return deptService.remove(deptId,parentId);
    }

    /**
     * 批量删除
     *
     * @param deptIds
     * @return
     */
    @PostMapping("/batchRemove")
    @ResponseBody
    @PreAuthorize("hasAuthority('system:dept:batchRemove')")
    public Result batchRemove(Long[] deptIds,Long[] parentIds) {

        return deptService.batchRemove(deptIds,parentIds);
    }


    /**
     * 部门树
     *
     * @return
     */
    @ResponseBody
    @GetMapping("/tree")
    public Result tree() {

        List<DeptDTO> allDeptList = deptService.list(new HashMap<String, Object>(4));

        List<TreeDTO> routerList = new ArrayList<>();
        for (DeptDTO dept : allDeptList) {
            if (dept.getParentId() == 0) {
                routerList.add(deptToTree(dept));
            }
        }
        listTreeRecursion(routerList, allDeptList);
        return Result.success(routerList);
    }

    /**
     * 递归查询
     *
     * @param treeList
     * @param allDeptList
     */
    private void listTreeRecursion(List<TreeDTO> treeList, List<DeptDTO> allDeptList) {
        if (!treeList.isEmpty()) {
            treeList.forEach(x -> {
                Long deptId = x.getKey();
                List<DeptEntity> childrenDeptList = allDeptList.stream()
                        .filter(y -> deptId.equals(y.getParentId())).collect(Collectors.toList());
                List<TreeDTO> childrenRouterList = new ArrayList<>();
                if (!childrenDeptList.isEmpty()) {
                    for (DeptEntity childrenDept : childrenDeptList) {
                        childrenRouterList.add(deptToTree(childrenDept));
                    }
                }
                x.setChildren(childrenRouterList);
                listTreeRecursion(childrenRouterList, allDeptList);
            });
        }
        return;
    }


    /**
     * 部门转树
     *
     * @param dept
     * @return
     */
    private TreeDTO deptToTree(DeptEntity dept) {
        return TreeDTO.builder()
                .key(dept.getDeptId())
                .value(dept.getDeptId())
                .parentId(dept.getParentId())
                .title(dept.getDeptName())
                .disabled(dept.getStatus() == 0 ? true : false)
                .build();
    }

}
